<?php
/**
 * Zendex (Zend (Framework) Extensions)
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://zfx.netatoo.fr/license/new-bsd
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to support@netatoo.fr so we can send you a copy immediately.
 *
 * @category   Zendex
 * @package    Zendex_Bootstrap
 * @copyright  Copyright (c) 2007 Netatoo FR S.A.R.L. (http://www.netatoo.fr)
 * @license    http://Zendex.netatoo.fr/license/new-bsd     New BSD License
 */

/**
 * @see Zendex_Bootstrap
 */
require_once 'Zendex/Bootstrap.php';

/**
 * @category   Zendex
 * @package    Zendex_Bootstrap
 * @copyright  Copyright (c) 2007 Netatoo FR S.A.R.L. (http://www.netatoo.fr)
 * @license    http://Zendex.netatoo.fr/license/new-bsd     New BSD License
 */
class Zendex_Bootstrap_Dispatcher_Zend extends Zendex_Bootstrap_Dispatcher_Abstract
{	
	
    /**
     * <Zend> for Zend
     * 
     * @param SimpleXMLElement $config
     * @return void
     */
    public function Zend($config) 
    {
        if(!is_null($config['version'])) {
            
            /** @see Zend_Version */
            require_once 'Zend/Version.php';
            
            $zfVersion = Zend_Version::VERSION;
            $version = (string) $config['version'];
            $compare = Zend_Version::compareVersion($version);
            
            if($compare === -1 or $compare > 0) {
                throw new Zendex_Bootstrap_Exception("The version defined by "
                    ."<Zend version=\"$version\"> does not match the version of "
                    ."Zend Framework that you use ($zfVersion)!");
            } 
            
            unset($zfVersion, $version, $compare);
        }
        
        $this->_dispatch($config);
    }
    
    /**
     * <Zend><Config> for Zend_Config
     * 
     * @param SimpleXMLElement $config
     * @return void
     */
    public function Config($config) 
    {
        foreach($config->File as $file) {
            $id         = $this->_toString($file['id'], 'default');
            $type       = $this->_toString($file['type'], 'Xml');
            $allowMod   = $this->_toBoolean($file->allowModifications, false);
            $cache      = $this->_toString($file['cache'], false);
            $filename   = trim((string)$file->filename);
            
            Zendex_Setup::addConfig($id, $type, $filename, $file->section, $allowMod, $cache);
            unset($id, $type, $allowMod, $cache, $filename);
        }
    }
    
    /**
     * <Zend><Db> for Zend_Db
     * 
     * @param SimpleXMLElement $config
     * @return void
     */
    public function Db($config) 
    {
        foreach($config->Adapter as $adapter) {
            $id         = $this->_toString($adapter['id'], 'default');
            $cache      = $this->_toString($adapter['cache'], false);            
            $adapter    = (array) $adapter;
            $adapter_name = (string) $adapter['adapter'];
            $params     = (array) $adapter['params'];
            $params['password'] = $this->_toString($params['password'], false);

            unset($adapter['@attributes']);
            
            Zendex_Setup::addDb($id, $adapter_name, $params, $cache);
            unset($id, $cache);
        }
        
        $this->_dispatch($config, 'Db_');
    }
    
    /**
     * <Zend><Db><Table><setDefaultAdapter /> 
     * for Zend_Db_Table_Abstract::setDefaultAdapter()
     * 
     * @param SimpleXMLElement $config
     * @return void
     */
    public function Db_Table($config) 
    {
        $this->_dispatch($config, 'Db_Table_');
    }
    
    /**
     * <Zend><Db><Table><setDefaultAdapter /> 
     * for Zend_Db_Table_Abstract::setDefaultAdapter()
     * 
     * @param SimpleXMLElement $config
     * @return void
     */
    public function Db_Table_setDefaultAdapter($config) 
    {
        if(!is_null($config['id'])) {
            
            $id = (string) $config['id'];

            /** @see Zend_Db_Table_Abstract */
            require_once 'Zend/Db/Table/Abstract.php';
            $db = Zendex_Setup::getDb($id);
            
            Zend_Db_Table_Abstract::setDefaultAdapter($db);
            unset($id);
        }
    }
    
    /**
     * <Zend><Db><Table><setDefaultMetadataCache /> 
     * for Zend_Db_Table_Abstract::setDefaultMetadataCache()
     * 
     * @param SimpleXMLElement $config
     * @return void
     */
    public function Db_Table_setDefaultMetadataCache($config) 
    {
        if(!is_null($config['id'])) {
            
            $id = (string) $config['id'];

            /** @see Zend_Db_Table_Abstract */
            require_once 'Zend/Db/Table/Abstract.php';

            $cache = Zendex_Setup::getCache($id);
            Zend_Db_Table_Abstract::setDefaultMetadataCache($cache);
            unset($id);
        }
    }
    
    /**
     * <Zend><Cache> for Zend_Cache
     * 
     * @param SimpleXMLElement $config
     * @return void
     */
    public function Cache($config) 
    {
        foreach($config->Core->Add as $core) {
                        
            if(is_null($core['frontend']) or is_null($core['backend'])) {
                continue;
            }
            
            $frontend   = (string) $core['frontend'];
            $backend    = (string) $core['backend'];
            $id         = $this->_toString($core['id'], null);
            $extends    = $this->_toString($core['extends']);
            $frontendOptions = $this->_toArray($core->frontendOptions);
            $backendOptions = $this->_toArray($core->backendOptions);
            
            if(!is_null($extends)) {
                $multipleId = explode(',', $extends);
                
                foreach($multipleId as $extendsId) {
                    
                    $extendsId = trim($extendsId);
                    
                    if(isset($config->Options->$extendsId->frontendOptions)) {
                        $extOptions = (array) $config->Options->$extendsId->frontendOptions;
                        $frontendOptions = $this->_arrayMergeRecursive($extOptions, $frontendOptions);
                    }
                    if(isset($config->Options->$extendsId->backendOptions)) {
                        $extOptions = (array) $config->Options->$extendsId->backendOptions;
                        $backendOptions = $this->_arrayMergeRecursive($extOptions, $backendOptions);
                    }
                    
                }
            }
            
            if(isset($frontendOptions['automatic_serialization'])) {
                $frontendOptions['automatic_serialization'] = $this->_toBoolean($frontendOptions['automatic_serialization'], true);
            }

            Zendex_Setup::addCache($id, $frontend, $backend, $frontendOptions, $backendOptions);
            unset($id, $frontend, $backend, $frontendOptions, $backendOptions);
        }
    }
    
    /**
     * <Zend><Controller> for Zend_Controller
     * 
     * @param SimpleXMLElement $config
     * @return void
     */
    public function Controller($config) 
    {
        $this->_dispatch($config, 'Controller_');    
    }
    
    /**
     * <Zend><Controller><Action> for Zend_Controller_Action
     * 
     * @param SimpleXMLElement $config
     * @return void
     */
    public function Controller_Action($config) 
    {
        /** @see Zend_Controller_Action */
        require_once 'Zend/Controller/Action.php';

        //Zend_Debug::dump($config);
        $this->_dispatch($config, 'Controller_Action_'); 
    }

    /**
     * <Zend><Controller><Action><addControllerDirectory>
     * for Zend_Controller_Front::addControllerDirectory()
     * 
     * @param SimpleXMLElement $config
     * @return void
     */
    public function Controller_Action_HelperBroker($config)
    {
        /** @see Zend_Controller_Action_HelperBroker */
        require_once 'Zend/Controller/Action/HelperBroker.php';
        
        $this->_dispatch($config, 'Controller_Action_HelperBroker_'); 
    }
    
    /**
     * <Zend><Controller><Action><HelperBroker><addPrefix>
     * for Zend_Controller_Action_HelperBroker::addPrefix()
     * 
     * @param SimpleXMLElement $config
     * @return void
     */
    public function Controller_Action_HelperBroker_addPrefix($config)
    {
        foreach($config->prefix as $prefix) {
            if(!$prefix) continue;                    
            Zend_Controller_Action_HelperBroker::addPrefix($prefix);
        }
    }
    
    /**
     * <Zend><Controller><Action><HelperBroker><addPath>
     * for Zend_Controller_Action_HelperBroker::addPath()
     * 
     * @param SimpleXMLElement $config
     * @return void
     */
    public function Controller_Action_HelperBroker_addPath($config)
    {
        foreach($config->Path as $path) {
            if(!$path) continue;
                
            $prefix = $this->_toString($path['prefix'], 'Zend_Controller_Action_Helper');
            $path = trim( (string) $path);
            
            Zend_Controller_Action_HelperBroker::addPath($path, $prefix);
            unset($path, $prefix);
        }
    }
    
    /**
     * <Zend><Controller><Front> for Zend_Controller_Front
     * 
     * @param SimpleXMLElement $config
     * @return void
     */
    public function Controller_Front($config) 
    {
        /** @see Zend_Controller_Front */
        require_once 'Zend/Controller/Front.php';
                        
        $this->_dispatch($config, 'Controller_Front_'); 
    }    

    /**
     * <Zend><Controller><Front><addControllerDirectory>
     * for Zend_Controller_Front::addControllerDirectory()
     * 
     * @param SimpleXMLElement $config
     * @return void
     */
    public function Controller_Front_addControllerDirectory($config)
    {
        foreach($config->dir as $directory) {
            $module = $this->_toString($directory['module']);
            $dir    = trim( (string) $directory);                        
            Zend_Controller_Front::getInstance()->addControllerDirectory($dir, $module);
            unset($module, $dir);
        }
    }
    
    /**
     * <Zend><Controller><Front><addModuleDirectory>
     * for Zend_Controller_Front::addModuleDirectory()
     * 
     * @param SimpleXMLElement $config
     * @return void
     */
    public function Controller_Front_addModuleDirectory($config)
    {
        foreach($config->dir as $directory) {
            $dir = trim( (string) $directory);
            Zend_Controller_Front::getInstance()->addModuleDirectory($dir);
            unset($dir);
        }
    }
    
    /**
     * <Zend><Controller><Front><setBaseUrl>
     * for Zend_Controller_Front::setBaseUrl()
     * 
     * @param SimpleXMLElement $config
     * @return void
     */
    public function Controller_Front_setBaseUrl($config)
    {
        Zend_Controller_Front::getInstance()->setBaseUrl( (string) $config );
    }

    /**
     * <Zend><Controller><Front><setControllerDirectory>
     * for Zend_Controller_Front::setControllerDirectory()
     * 
     * @param SimpleXMLElement $config
     * @return void
     */
    public function Controller_Front_setControllerDirectory($config)
    {
        foreach($config->dir as $directory) {
            $module = $this->_toString($directory['module']);
            $dir    = trim( (string) $directory);                        
            Zend_Controller_Front::getInstance()->setControllerDirectory($dir, $module);
            unset($module, $dir);
        }
    }
    
    /**
     * <Zend><Controller><Front><setDefaultModule>
     * for Zend_Controller_Front::setDefaultModule()
     * 
     * @param SimpleXMLElement $config
     * @return void
     */
    public function Controller_Front_setDefaultModule($config)
    {
        Zend_Controller_Front::getInstance()->setDefaultModule( (string) $config );
    }
    
    /**
     * <Zend><Controller><Front><setDefaultControllerName>
     * for Zend_Controller_Front::setDefaultControllerName()
     * 
     * @param SimpleXMLElement $config
     * @return void
     */
    public function Controller_Front_setDefaultControllerName($config)
    {
        Zend_Controller_Front::getInstance()->setDefaultControllerName( (string) $config );
    }
    
    /**
     * <Zend><Controller><Front><setDispatcher>
     * for Zend_Controller_Front::setDispatcher()
     * 
     * @param SimpleXMLElement $config
     * @return void
     */
    public function Controller_Front_setDispatcher($config)
    {
        Zend_Controller_Front::getInstance()->setDispatcher( (string) $config );
    }
    
    /**
     * <Zend><Controller><Front><setModuleControllerDirectoryName>
     * for Zend_Controller_Front::setModuleControllerDirectoryName()
     * 
     * @param SimpleXMLElement $config
     * @return void
     */
    public function Controller_Front_setModuleControllerDirectoryName($config)
    {
        Zend_Controller_Front::getInstance()->setModuleControllerDirectoryName( (string) $config );
    }
    
    /**
     * <Zend><Controller><Front><setParams>
     * for Zend_Controller_Front::setParams()
     * 
     * @param SimpleXMLElement $config
     * @return void
     */
    public function Controller_Front_setParams($config)
    {
        Zend_Controller_Front::getInstance()->setParams( (array) $config );
    }
    
    /**
     * <Zend><Controller><Front><setRequest>
     * for Zend_Controller_Front::setRequest()
     * 
     * @param SimpleXMLElement $config
     * @return void
     */
    public function Controller_Front_setRequest($config)
    {
        Zend_Controller_Front::getInstance()->setRequest( (string) $config );
    }
    
    /**
     * <Zend><Controller><Front><setRouter>
     * for Zend_Controller_Front::setRouter()
     * 
     * @param SimpleXMLElement $config
     * @return void
     */
    public function Controller_Front_setRouter($config)
    {
        Zend_Controller_Front::getInstance()->setRouter( (string) $config );
    }
    
    /**
     * <Zend><Controller><Front><returnResponse>
     * for Zend_Controller_Front::returnResponse()
     * 
     * @param SimpleXMLElement $config
     * @return void
     */
    public function Controller_Front_returnResponse($config)
    {
        Zend_Controller_Front::getInstance()->returnResponse( (string) $config );
    }
    
    /**
     * <Zend><Controller><Front><registerPlugin>
     * for Zend_Controller_Front::registerPlugin()
     * 
     * @param SimpleXMLElement $config
     * @return void
     */
    public function Controller_Front_registerPlugin($config)
    {
        foreach($config->Plugin as $plugin) {
            
            if(!isset($plugin['className'])) continue;
            $pluginClass = (string) $plugin['className'];
            $stackIndex  = $this->_toInt($plugin['stackIndex'], null);
            
            /** @see Zend_Loader */
            require_once 'Zend/Loader.php';
            Zend_Loader::loadClass($pluginClass);
            $pluginInstance = new $pluginClass();
            Zend_Controller_Front::getInstance()->registerPlugin($pluginInstance, $stackIndex);
            unset($pluginClass);
        }
    }
    
    /**
     * <Zend><Controller><Router> for Zend_Controller_Router
     * 
     * @param SimpleXMLElement $config
     * @return void
     */
    public function Controller_Router($config) 
    {                        
        $this->_dispatch($config, 'Controller_Router_'); 
    }
    
     /**
     * <Zend><Controller><Router><Route> 
     * for Zend_Controller_Router_Route
     * 
     * @param SimpleXMLElement $config
     * @return void
     */
    public function Controller_Router_removeDefaultRoutes($config) 
    {
        $router = Zend_Controller_Front::getInstance()->getRouter();
        $router->removeDefaultRoutes();
    }
    
    /**
     * <Zend><Controller><Router><Route> 
     * for Zend_Controller_Router_Route
     * 
     * @param SimpleXMLElement $config
     * @return void
     */
    public function Controller_Router_Route($config) 
    {
        if(is_null($config['route'])) {
            return;
        }
        
        /** @see Zend_Controller_Router_Route */
        require_once 'Zend/Controller/Router/Route.php';

        $route      = (string) $config['route'];
        $id         = $this->_toString($config['id'], 'route_' . mt_rand(0, 2500));
        $defaults   = $this->_toArray($config->defaults);
        $reqs       = $this->_toArray($config->reqs);
        
        $router = Zend_Controller_Front::getInstance()->getRouter();
        $router->addRoute($id, new Zend_Controller_Router_Route(
            $route, $defaults, $reqs
        ));
        
        unset($route, $defaults, $reqs, $id);
    }
    
    /**
     * <Zend><Controller><Router><RouteStatic> 
     * for Zend_Controller_Router_RouteStatic
     * 
     * @param SimpleXMLElement $config
     * @return void
     */
    public function Controller_Router_RouteStatic($config) 
    {
        if(is_null($config['route'])) {
            return;
        }
        
        /** @see Zend_Controller_Router_Route */
        require_once 'Zend/Controller/Router/Route/Static.php';

        $route      = (string) $config['route'];
        $id         = $this->_toString($config['id'], 'route_' . mt_rand(0, 2500));
        $defaults   = $this->_toArray($config->defaults);
        
        $router = Zend_Controller_Front::getInstance()->getRouter();
        $router->addRoute($id, new Zend_Controller_Router_Route_Static(
            $route, $defaults
        ));
        
        unset($route, $defaults, $id);
    }
    
    /**
     * <Zend><Controller><Router><RouteRegex> 
     * for Zend_Controller_Router_RouteRegex
     * 
     * @param SimpleXMLElement $config
     * @return void
     */
    public function Controller_Router_RouteRegex($config) 
    {
        if(is_null($config['route'])) {
            return;
        }
        
        /** @see Zend_Controller_Router_Route */
        require_once 'Zend/Controller/Router/Route/Regex.php';
        
        $route      = (string) $config['route'];
        $id         = $this->_toString($config['id'], 'route_' . mt_rand(0, 2500));
        $defaults   = $this->_toArray($config->defaults);
        $maps       = $this->_toArray($config->maps);
        $reverse    = $this->_toString($config->reverse);
        
        $router = Zend_Controller_Front::getInstance()->getRouter();
        $router->addRoute($id, new Zend_Controller_Router_Route_Regex(
            $route, $defaults, $maps, $reverse
        ));
        
        unset($route, $defaults, $maps, $reverse, $id);
    }
    
    /**
     * <Zend><Loader> for Zend_Loader
     * 
     * @param SimpleXMLElement $config
     * @return void
     */
    public function Loader($config) 
    {
        if(isset($config->registerAutoload)) {
            $autoLoad = $config->registerAutoload;    
            $class    = $this->_toString($autoLoad->class, 'Zend_Loader');
            $enabled  = $this->_toBoolean($autoLoad->enabled, true);

            require_once 'Zend/Loader.php';
            Zend_Loader::registerAutoload($class, $enabled);

            unset($autoLoad, $class, $enabled);
        }
    }
}